<?php


namespace app\privatearea\controller;


use app\common\cachemodel\privatearea\PrivateAreaAstro;
use app\common\lib\exception\ApiException;
use think\Controller;

class AstroAuth extends Controller
{
    protected $headers = null;
    protected $astro = null;
    protected $errermsg = '';
    protected $is_simulated = false;

    public function _initialize()
    {
        parent::_initialize();

        $this->headers = $this->request->header();

        if (!$this->isLogin())
        {
            throw new ApiException($this->errermsg, 200, config('code.denied'));
        }
    }

    public function isLogin()
    {
        if (!isset($this->headers['access-token']) || empty($this->headers['access-token']))
        {
            $this->errermsg = '您的账户登录过期，请重新登录。';
            return false;
        }
        // access-token AES解密
        $accessUserToken = $this->decryptWithOpenssl($this->headers['access-token']);

        if (empty($accessUserToken)) throw new ApiException('前往登录', 200, 405);

        if (!preg_match('/||/', $accessUserToken))
        {
            $this->errermsg = '您的账户登录过期，请重新登录。';
            return false;
        }

        [$token, $astroId] = explode('||', $accessUserToken);

        // 账号模拟
        $simulation = config('app.simulation');

        if ($astroId == $simulation['from'])
        {
            $astroId = $simulation['to'] ?: $astroId;
            if ($astroId == $simulation['to'])
            {   // 模拟登陆
                $this->is_simulated = true;
            }
        }

        $astroInfo = (new PrivateAreaAstro())->getPrivateAreaInfo($astroId);

        if (!$astroInfo || ($astroInfo['status'] != 1 && $this->headers['app-type'] !== 'manage') || $astroInfo['token'] !== $token || $this->request->time() > $astroInfo['token_expire'])
        {   // 判断token是否过期 并且账户状态正常
            throw new ApiException('登录失效', 200, config('code.denied'));
        }

        $this->astro = $astroInfo;

        return true;
    }

    /**
     * 加密字符串
     * @param string $data 字符串
     * @return string
     */
    protected function encryptWithOpenssl($data): string
    {
        try
        {
            $config = config('privatearea');
            return base64_encode(openssl_encrypt($data, $config['aes_method'], $config['aes_key'], OPENSSL_RAW_DATA, $config['aes_iv']));
        }
        catch (\Exception $e)
        {
            return '';
        }

    }

    /**
     * 解密字符串
     * @param string $data 字符串
     * @return string
     */
    protected function decryptWithOpenssl($data): string
    {
        try
        {
            $config = config('privatearea');
            return openssl_decrypt(base64_decode($data), $config['aes_method'], $config['aes_key'], OPENSSL_RAW_DATA, $config['aes_iv']);
        }
        catch (\Exception $e)
        {
            return '';
        }
    }
}
